package com.syqc.utils

import com.syqc.comlib.utils.AppContext
import com.syqc.entity.ChooseTime
import com.syqc.monitor.R
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Date
import java.util.GregorianCalendar
import java.util.Locale

/**
 *@Author Jasper
 *@Time   2020/8/8
 *@Desc   时间工具类
 */
class TimeUtil private constructor() {
    private val simpleFormat = SimpleDateFormat(simplePattern, Locale.getDefault())
    private val normalFormat = SimpleDateFormat(normalPattern, Locale.getDefault())
    private val allFormat = SimpleDateFormat(allPattern, Locale.getDefault())
    private val lackFormat = SimpleDateFormat(lackPattern, Locale.getDefault())
    private val hmsFormat = SimpleDateFormat(hmsPattern, Locale.getDefault())


    companion object {
        const val simplePattern = "yyyy-MM-dd"
        const val normalPattern = "yyyy-MM-dd HH:mm"
        const val hmsPattern = "yyyy-MM-dd HH:mm:ss"
        const val allPattern = "yyyyMMddHHmmss"
        const val lackPattern = "yyMMddHHmmss"

        const val simpleDate = "2000-01-01"
        const val normalDate = "2000-01-01 00:00"

        //结束时间
        const val simpleDateEnd = "2100-11-30"

        //结束时间
        const val normalDateEnd = "2100-11-30 23:59"
        const val normalDateEnds = "2050-11-30 23:59"

        const val zeroHms = "00:00:00"

        //时间选择7天
        const val TIME_SEVEN = 1

        //时间选择10天
        const val TIME_TEN = 2

        //时间选择30天
        const val TIME_THIRTY = 3
        val instance: TimeUtil
                by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED, initializer = ::TimeUtil)


        // 获取当天的开始时间
        fun getDayBegin(): Date {
            val cal: Calendar = GregorianCalendar()
            cal[Calendar.HOUR_OF_DAY] = 0
            cal[Calendar.MINUTE] = 0
            cal[Calendar.SECOND] = 0
            cal[Calendar.MILLISECOND] = 0
            return cal.time
        }

        // 获取当天的结束时间
        fun getDayEnd(): Date {
            val cal: Calendar = GregorianCalendar()
            cal[Calendar.HOUR_OF_DAY] = 23
            cal[Calendar.MINUTE] = 59
            cal[Calendar.SECOND] = 59
            return cal.time
        }

        // 获取昨天的开始时间
        fun getBeginDayOfYesterday(): Date {
            val cal: Calendar = GregorianCalendar()
            cal.time = getDayBegin()
            cal.add(Calendar.DAY_OF_MONTH, -1)
            return cal.time
        }

        // 获取昨天的结束时间
        fun getEndDayOfYesterday(): Date {
            val cal: Calendar = GregorianCalendar()
            cal.time = getDayEnd()
            cal.add(Calendar.DAY_OF_MONTH, -1)
            return cal.time
        }


        // 获取昨天的开始时间
        fun getBeginDayOfThree(): Date {
            val cal: Calendar = GregorianCalendar()
            cal.time = getDayBegin()
            cal.add(Calendar.DAY_OF_MONTH, -2)
            return cal.time
        }

        // 获取昨天的结束时间
        fun getEndDayOfThree(): Date {
            val cal: Calendar = GregorianCalendar()
            cal.time = getDayEnd()
            cal.add(Calendar.DAY_OF_MONTH, -2)
            return cal.time
        }
    }

    //
    fun getTime2Long(time: String) {
        simpleFormat.parse(time).time
    }

    /**
     * 获取当前时间
     */
    fun getNowTime(isSimple: Boolean = false): String {
        return if (isSimple) {
            simpleFormat.format(Date())
        } else {
            normalFormat.format(Date())
        }
    }

    fun formatByDate(date: Date, isSimple: Boolean = false): String {
        return if (isSimple) {
            simpleFormat.format(date)
        } else {
            normalFormat.format(date)
        }
    }

    /**
     *获取yyyyMMddHHmmss格式时间
     */
    fun getAllTime(time: Long = 0L): String {
        return if (time == 0L) allFormat.format(Date())
        else allFormat.format(time)
    }

    fun timeToString(time: Long): String {
        return allFormat.format(time)
    }


    fun timeToString(time: Long, isSimple: Boolean = false): String {
        return if (isSimple) {
            simpleFormat.format(time)
        } else {
            normalFormat.format(time)
        }
    }

    /**
     * 获取时间
     */
    private fun getParseTime(time: String, isSimple: Boolean = false): Long = if (isSimple) {
        simpleFormat.parse(time).time
    } else {
        normalFormat.parse(time).time
    }

    /**
     * 获取时间差
     */
    fun getDiffTime(startTime: String, endTime: String, isSimple: Boolean = false): Long =
        if (isSimple) {
            getParseTime(endTime, isSimple) - getParseTime(startTime, isSimple)
        } else {
            getParseTime(endTime) - getParseTime(startTime)
        }

    /**
     * 获取yyyyMMddHHmmss
     */
    fun getDiffAllTime(startTime: String, endTime: String): Long =
        (allFormat.parse(endTime)?.time ?: 0) - (allFormat.parse(startTime)?.time ?: 0)

    /**
     * 获取时间差
     */
    fun getAddSimpleTime(time: String, num: Int, type: Int): String =
        simpleFormat.format((simpleFormat.parse(time)?.time ?: 0) + getMillis(num, type))

    /**
     * 获取yyMMddHHmmss
     */
    fun getDiffLockTime(startTime: String, endTime: String): Long =
        (lackFormat.parse(endTime)?.time ?: 0) - (lackFormat.parse(startTime)?.time ?: 0)

    /**
     * 获取yyMMddHHmmss
     */
    fun getAddLockTime(endTime: String, time: Long): String =
        lackFormat.format((lackFormat.parse(endTime)?.time ?: 0) + time)

    fun getTimeLong(time: String): Long =
        lackFormat.parse(time)?.time ?: 0

    fun formatToNormal(yyTime: String): String {
        return normalFormat.format(allFormat.parse("20$yyTime")?.time ?: 0)
    }

    fun formatToHMS(yyTime: String): String {
        return hmsFormat.format(allFormat.parse("20$yyTime")?.time ?: 0)
    }

    fun reduceHms(startTime: String, endTime: String): Boolean {
        return (allFormat.parse(startTime)?.time ?: 0) >= (allFormat.parse(endTime)?.time ?: 0)
    }

    fun normal2simple(time: String): String {
        return simpleFormat.format(allFormat.parse(time)?.time ?: 0)
    }

    fun formatHm(time: String): String = time.replace("-", "")
        .replace(" ", "")
        .replace(":", "")

    fun formatHms(time: String): String = time.replace("-", "")
        .replace(" ", "")
        .replace(":", "") + "00"

    fun formatEndHms(time: String): String = time.replace("-", "")
        .replace(" ", "")
        .replace(":", "") + "59"

    fun normalTime(time: Long): String = normalFormat.format(time)

    fun simpleTime(time: Long): String = simpleFormat.format(time)

    fun isSimpleOverNow(time: String): Boolean {
        val endTime = simpleFormat.format(System.currentTimeMillis())
        val timeReduce =
            (simpleFormat.parse(time)?.time ?: 0) - (simpleFormat.parse(endTime)?.time ?: 0)
        return timeReduce >= 0
    }

    fun isAllOverNow(time: String): Boolean {
        val timeReduce = (allFormat.parse(formatHm(time))?.time ?: 0) - System.currentTimeMillis()
        return timeReduce >= 0
    }

    /**
     * 根据类型 时间
     */
    fun getMillis(num: Int, type: Int): Long {
        if (num <= 0) return 0
        return when (type) {
            1 -> num * 1000L
            2 -> num * 60000L
            3 -> num * 3600000L
            4 -> num * 24 * 3600000L
            else -> 0
        }
    }

    /***
     * 格式化时间
     * @return
     */
    fun formatLongTime(time: Long): String {
        val mm = time / 1000
        val h = mm / 3600
        var m = mm % 3600
        val s = m % 60
        m /= 60

        return String.format("%02d:%02d:%02d", h, m, s)
    }

    /***
     * 格式化时间
     * @return
     */
    fun formatSecondTime(second: Long): String {
        val h = second / 3600
        var m = second % 3600
        val s = m % 60
        m /= 60
        return String.format("%02d:%02d:%02d", h, m, s)
    }

    /***
     * 格式化时间
     * @return
     */
    fun formatTime(time: Int): String {
        val h = time / 3600
        var m = time % 3600
        val s = m % 60
        m /= 60
        return String.format("%02d:%02d:%02d", h, m, s)
    }

    /***
     * 格式化时间
     * @return
     */
    fun formatTime(second: Long): String {
        if (second == 0L) {
            return "0${unit_s}"
        }
        val h = second / 3600
        var m = second % 3600
        val s = m % 60
        m /= 60
        val d = h / 24
        val hour = h % 24
        return if (d != 0L) {
            String.format("%02d${unit_d}%02d${unit_h}%02d${unit_m}%02d${unit_s}", d, hour, m, s)
        } else {
            if (h != 0L) {
                String.format("%02d${unit_h}%02d${unit_m}%02d${unit_s}", h, m, s)
            } else {
                if (m != 0L) {
                    String.format("%02d${unit_m}%02d${unit_s}", m, s)
                } else {
                    String.format("%02d${unit_s}", s)
                }
            }
        }
    }

    /***
     * 格式化时间
     * @return
     */
    fun formatTimeDesc(time: Int): String {
        val h = time / 3600
        var m = time % 3600
        val s = m % 60
        m /= 60
        return String.format("%02d$unit_h%02d$unit_m%02d$unit_s", h, m, s)
    }


    fun formatMin(min: Int): String {
        if (min > 60) {
            val h = min / 60
            val m = min % 60
            return String.format("%02d$unit_h%02d$unit_m", h, m)
        } else {
            return String.format("%02d$unit_m", min)
        }

    }

    private val unit_d = AppContext.getDescById(R.string.unit_day_)
    private val unit_h = AppContext.getDescById(R.string.unit_hour)
    private val unit_m = AppContext.getDescById(R.string.unit_minute_)
    private val unit_s = AppContext.getDescById(R.string.unit_second_)

    /**
     * 获取时间差
     */
    fun getDiffSimpleTime(time: String, num: Int, type: Int): String =
        simpleFormat.format(simpleFormat.parse(time).time - getMillis(num, type))

    /**
     * 获取时间差
     */
    fun getDiffTime(time: String, num: Int, type: Int): String =
        normalFormat.format(normalFormat.parse(time).time - getMillis(num, type))

    private val timeListOne: MutableList<ChooseTime> by lazy { ArrayList<ChooseTime>() }
    private val timeListTwo: MutableList<ChooseTime> by lazy { ArrayList<ChooseTime>() }
    private val timeListThree: MutableList<ChooseTime> by lazy { ArrayList<ChooseTime>() }

    fun getDiffDay(endTime: String): Long {
        val nowTime = getNowTime(true)
        return (simpleFormat.parse(endTime).time - simpleFormat.parse(nowTime).time) / 86400000
    }

    /**
     * type  1:7day 2:10day 3:30day 时间类型
     */
    fun initChooseTime(isThirty: Boolean): MutableList<ChooseTime> {
        if (isThirty) {
            if (timeListThree.isNotEmpty()) return timeListThree
            timeListThree.add(
                ChooseTime(
                    timeNameId = R.string.desc_time_yesterday,
                    timeNum = 1,
                    timeType = 2
                )
            )
            timeListThree.add(
                ChooseTime(
                    timeNameId = R.string.desc_time_three_day,
                    timeNum = 2
                )
            )
            timeListThree.add(
                ChooseTime(
                    timeNameId = R.string.desc_time_seven_day,
                    timeNum = 6
                )
            )
            timeListThree.add(
                ChooseTime(
                    timeNameId = R.string.desc_time_ten_day,
                    timeNum = 9
                )
            )
            timeListThree.add(
                ChooseTime(
                    timeNameId = R.string.desc_time_fifteen_day,
                    timeNum = 14
                )
            )
            timeListThree.add(
                ChooseTime(
                    timeNameId = R.string.desc_time_twenty_day,
                    timeNum = 19
                )
            )
            timeListThree.add(
                ChooseTime(
                    timeNameId = R.string.desc_time_twenty_five_day,
                    timeNum = 24
                )
            )
            timeListThree.add(
                ChooseTime(
                    timeNameId = R.string.desc_time_thirty_day,
                    timeNum = 30
                )
            )
            return timeListThree
        } else {
            if (timeListOne.isNotEmpty()) return timeListOne
            timeListOne.add(
                ChooseTime(
                    timeNameId = R.string.desc_time_one_hour,
                    timeType = 3,
                    timeNum = 1
                )
            )
            timeListOne.add(
                ChooseTime(
                    timeNameId = R.string.desc_time_three_hour,
                    timeType = 3,
                    timeNum = 3
                )
            )
            timeListOne.add(
                ChooseTime(
                    timeNameId = R.string.desc_time_five_hour,
                    timeType = 3,
                    timeNum = 5
                )
            )
            timeListOne.add(
                ChooseTime(
                    timeNameId = R.string.desc_time_ten_hour,
                    timeType = 3,
                    timeNum = 10
                )
            )
            timeListOne.add(
                ChooseTime(
                    timeNameId = R.string.desc_time_today,
                    timeType = 1,
                    timeNum = 0
                )
            )
            timeListOne.add(
                ChooseTime(
                    timeNameId = R.string.desc_time_yesterday,
                    timeNum = 1,
                    timeType = 2

                )
            )
            timeListOne.add(
                ChooseTime(
                    timeNameId = R.string.desc_time_two_day,
                    timeNum = 2
                )
            )
            timeListOne.add(
                ChooseTime(
                    timeNameId = R.string.desc_time_three_day_,
                    timeNum = 3
                )
            )
            return timeListOne
        }

    }

    //获取四天时间
    fun getTimeList(): MutableList<ChooseTime> {
        if (timeListTwo.isNotEmpty()) return timeListTwo
        timeListTwo.add(
            ChooseTime(
                timeNameId = R.string.desc_time_today,
                timeType = 1,
                timeNum = 0
            )
        )
        timeListTwo.add(
            ChooseTime(
                timeNameId = R.string.desc_time_yesterday,
                timeNum = 1,
                timeType = 2

            )
        )
        timeListTwo.add(
            ChooseTime(
                timeNameId = R.string.desc_time_two_day,
                timeNum = 2
            )
        )
        timeListTwo.add(
            ChooseTime(
                timeNameId = R.string.desc_time_three_day_,
                timeNum = 3
            )
        )
        return timeListTwo
    }
}